The software utility cron also known as cron job is a time-based job scheduler in Unix-like computer operating systems. Users who set up and maintain software environments use cron to schedule jobs (commands or shell scripts) to run periodically at fixed times, dates, or intervals.
On this tutorial we're going to cover how to automatically update our linux-based system:
Among the most popular linux distros is debian, or debian-based systems. Cron should always be there by default:
root@home:~# apt search cron
cron/stable,now 3.0pl1-134+deb10u1 amd64 [installed]
process scheduling daemon
root@home:~# apt install cron
So what are the commands that we want to run ?
root@home:~# apt update -y
root@home:~# apt upgrade -y
root@home:~# apt autoremove -y
The first one updates the packages, the second one upgrades the distribution, and the last one removes the unused packages, let's add a cronjob for it:
root@home:~# crontab -e
0 3 * * * "/var/www/nextcloud/data/nothing/files/backup.sh"
0 2 * * * root (apt update -y && apt -y upgrade && apt autoremove -y) > /dev/null
:wq
Here you see that i'm executing a backup bashscript everyday at 3 am, and running apt update , upgrade and autoremove at 2 am.
wget https://github.com/cronitorio/cronitor-cli/releases/download/28.8/linux_amd64.tar.gz
sudo tar xvf linux_amd64.tar.gz -C /usr/bin/
sudo cronitor configure --api-key 1234567890
To debug cronjobs i use cronitor
root@home:~# cronitor list
----► Checking user "root" crontab
+-------------------+------------------------------------------------------------------------------------------------------+
| SCHEDULE | COMMAND |
+-------------------+------------------------------------------------------------------------------------------------------+
| 20 0 * * * | "/root/.acme.sh/acme.sh" |
| | --cron --home "/root/.acme.sh" |
| | > /dev/null |
| 0 3 * * * | /usr/bin/ansible-playbook |
| | /root/playbooks/update.yml |
| 0 3 * * * | "/var/www/nextcloud/data/nothing/files/backup.sh" |
| 0 2 * * * | (apt-get update && apt-get -y |
| | upgrade && apt autoremove) > |
| | /dev/null |
+-------------------+------------------------------------------------------------------------------------------------------+
----► Checking /etc/crontab
+-------------------+------------------------------------------------------------------------------------------------------+
| SCHEDULE | COMMAND |
+-------------------+------------------------------------------------------------------------------------------------------+
| 17 * * * * | cd / && run-parts --report |
| | /etc/cron.hourly |
| 25 6 * * * | test -x /usr/sbin/anacron || |
| | ( cd / && run-parts --report |
| | /etc/cron.daily ) |
| 47 6 * * 7 | test -x /usr/sbin/anacron || |
| | ( cd / && run-parts --report |
| | /etc/cron.weekly ) |
| 52 6 1 * * | test -x /usr/sbin/anacron || |
| | ( cd / && run-parts --report |
| | /etc/cron.monthly ) |
+-------------------+------------------------------------------------------------------------------------------------------+
----► Checking /etc/cron.d/php
+-------------------+------------------------------------------------------------------------------------------------------+
| SCHEDULE | COMMAND |
+-------------------+------------------------------------------------------------------------------------------------------+
| 09,39 * * * * | [ -x /usr/lib/php/sessionclean |
| | ] && if [ ! -d |
| | /run/systemd/system ]; then |
| | /usr/lib/php/sessionclean; fi |
+-------------------+------------------------------------------------------------------------------------------------------+
----► Checking /etc/cron.d/sysstat
+-------------------+------------------------------------------------------------------------------------------------------+
| SCHEDULE | COMMAND |
+-------------------+------------------------------------------------------------------------------------------------------+
| 5-55/10 * * * * | command -v debian-sa1 > |
| | /dev/null && debian-sa1 1 1 |
| 59 23 * * * | command -v debian-sa1 > |
| | /dev/null && debian-sa1 60 2 |
+-------------------+------------------------------------------------------------------------------------------------------+
Here i removed the >/dev/null to be able to see the output of our cronjob, selecting it with cronitor:
root@home:~# crontab -e
crontab: installing new crontab
root@home:~# cronitor select
✔ (apt-get update && apt-get -y upgrade && apt autoremove)
----► Running command: (apt-get update && apt-get -y upgrade && apt autoremove)
Hit:1 http://deb.debian.org/debian buster InRelease
Hit:2 http://apt.postgresql.org/pub/repos/apt buster-pgdg InRelease
Reading package lists...
Reading package lists...
Building dependency tree...
Reading state information...
Calculating upgrade...
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
Reading package lists...
Building dependency tree...
Reading state information...
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
----► ✔ Command successful Elapsed time 4.145s
And there you have it! We have been able to test update the repos, upgrade the distro and remove the unused packages with our cronjob, which will run everyday at 2 AM.
Arch linux distributions require daily upgrades because it is a rolling release, so one way to do it is to manually upgrade your system like so:
[ 10.0.0.10/16 ] [ /dev/pts/51 ] [Nextcloud/blog]
→ sudo pacman -Syu
[sudo] password for nothing:
:: Synchronizing package databases...
core 132.9 KiB 1384 KiB/s 00:00 [--------------------------------------------------------] 100%
extra 1557.9 KiB 3.22 MiB/s 00:00 [--------------------------------------------------------] 100%
community 5.6 MiB 4.27 MiB/s 00:01 [--------------------------------------------------------] 100%
multilib 149.1 KiB 4.85 MiB/s 00:00 [--------------------------------------------------------] 100%
:: Starting full system upgrade...
resolving dependencies...
looking for conflicting packages...
Package (8) Old Version New Version Net Change Download Size
community/arandr 0.1.10-5 0.1.10-6 0.00 MiB 0.08 MiB
multilib/lib32-systemd 248.2-1 248.3-1 0.00 MiB 0.56 MiB
extra/libidn 1.36-1 1.37-1 -0.03 MiB 0.21 MiB
extra/perl-http-message 6.30-1 6.31-1 0.00 MiB 0.07 MiB
core/systemd 248.2-2 248.3-1 0.00 MiB 6.31 MiB
core/systemd-libs 248.2-2 248.3-1 0.00 MiB 0.54 MiB
core/systemd-sysvcompat 248.2-2 248.3-1 0.00 MiB 0.01 MiB
community/tpm2-tss 3.0.3-1 3.1.0-1 0.13 MiB 0.81 MiB
Total Download Size: 8.59 MiB
Total Installed Size: 32.46 MiB
Net Upgrade Size: 0.10 MiB
:: Proceed with installation? [Y/n] y
If you want to do cronjobs to automate arch linux updates, be very careful because pacman may need to do drastic updates from time to time, like the /lib -> /usr/lib transitioning, So let's make sure that pacman gives enough verbose to at least say what went wrong just in case if it does:
[ 10.0.0.10/16 ] [ /dev/pts/70 ] [~]
→ sudo pacman -Syu --noconfirm
That's the command we want to run, if we want to automatically update arch. This may break your install so make sure that it functions properly and do so regularly, checking pacman's logs in /var/log/pacman.log
[ 10.0.0.10/16 ] [ /dev/pts/72 ] [~]
→ tail -f /var/log/pacman.log
[2021-05-18T14:51:02+0200] [ALPM] running '30-systemd-daemon-reload.hook'...
[2021-05-18T14:51:02+0200] [ALPM] running '30-systemd-update.hook'...
[2021-05-18T14:58:39+0200] [PACMAN] Running 'pacman -Syu --noconfirm'
[2021-05-18T14:58:39+0200] [PACMAN] synchronizing package lists
[2021-05-18T14:58:42+0200] [PACMAN] starting full system upgrade
[2021-05-18T14:58:43+0200] [ALPM] transaction started
[2021-05-18T14:58:43+0200] [ALPM] upgraded libimagequant (2.15.0-1 -> 2.15.1-1)
[2021-05-18T14:58:43+0200] [ALPM] upgraded svt-hevc (1.5.0-1 -> 1.5.1-1)
[2021-05-18T14:58:43+0200] [ALPM] transaction completed
[2021-05-18T14:58:43+0200] [ALPM] running '30-systemd-update.hook'...
[2021-05-18T15:00:35+0200] [PACMAN] Running 'pacman -Syu --noconfirm'
[2021-05-18T15:00:35+0200] [PACMAN] synchronizing package lists
[2021-05-18T15:00:35+0200] [PACMAN] starting full system upgrade
[2021-05-18T15:00:39+0200] [PACMAN] Running 'pacman -Syu --noconfirm'
[2021-05-18T15:00:39+0200] [PACMAN] synchronizing package lists
[2021-05-18T15:00:40+0200] [PACMAN] starting full system upgrade
Now let's setup our cronjob using cronie:
[ 10.0.0.10/16 ] [ /dev/pts/70 ] [~]
→ sudo pacman -S cronie
[ 10.0.0.10/16 ] [ /dev/pts/70 ] [~]
→ systemctl status cronie
○ cronie.service - Periodic Command Scheduler
Loaded: loaded (/usr/lib/systemd/system/cronie.service; disabled; vendor preset: disabled)
Active: inactive (dead)
[ 10.0.0.10/16 ] [ /dev/pts/70 ] [~]
→ systemctl enable --now cronie
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-unit-files ====
Authentication is required to manage system service or unit files.
Authenticating as: nothing
Password:
==== AUTHENTICATION COMPLETE ====
Created symlink /etc/systemd/system/multi-user.target.wants/cronie.service → /usr/lib/systemd/system/cronie.service.
[ 10.0.0.10/16 ] [ /dev/pts/70 ] [~]
→ systemctl status cronie
● cronie.service - Periodic Command Scheduler
Loaded: loaded (/usr/lib/systemd/system/cronie.service; enabled; vendor preset: disabled)
Active: active (running) since Tue 2021-05-18 14:51:30 CEST; 1s ago
Main PID: 1926934 (crond)
Tasks: 1 (limit: 38425)
Memory: 448.0K
CPU: 1ms
CGroup: /system.slice/cronie.service
└─1926934 /usr/bin/crond -n
May 18 14:51:30 nowhere systemd[1]: Started Periodic Command Scheduler.
May 18 14:51:30 nowhere crond[1926934]: (CRON) STARTUP (1.5.7)
May 18 14:51:30 nowhere crond[1926934]: (CRON) INFO (Syslog will be used instead of sendmail.)
May 18 14:51:30 nowhere crond[1926934]: (CRON) INFO (RANDOM_DELAY will be scaled with factor 6% if used.)
May 18 14:51:30 nowhere crond[1926934]: (CRON) INFO (running with inotify support)
[ 10.0.0.10/16 ] [ /dev/pts/76 ] [/tmp]
→ sudo -i
[sudo] password for nothing:
root@nowhere: ~ # crontab -e
crontab: installing new crontab
0 2 * * * /usr/bin/pacman -Syu --noconfirm
:wq
root@nowhere: ~ # exit
logout
Now let's use cronitor to test our cronjob:
[ 10.0.0.10/16 ] [ /dev/pts/75 ] [/tmp]
→ curl -sOL https://cronitor.io/dl/cronitor-stable-linux-amd64.tgz
[ 10.0.0.10/16 ] [ /dev/pts/75 ] [/tmp]
→ sudo tar xvf cronitor-stable-linux-amd64.tgz -C /usr/bin/
[sudo] password for nothing:
cronitor
[ 10.0.0.10/16 ] [ /dev/pts/75 ] [/tmp]
→ sudo cronitor configure --api-key 1234567890
Error: Problem with config file at : Config File "cronitor" Not Found in "[/etc/cronitor]"
[ 10.0.0.10/16 ] [ /dev/pts/75 ] [/tmp]
→ sudo cronitor configure --api-key 1234567890
[ 10.0.0.10/16 ] [ /dev/pts/75 ] [/tmp]
→ which cronitor
/usr/bin/cronitor
[ 10.0.0.10/16 ] [ /dev/pts/75 ] [/tmp]
→ cronitor select
root@nowhere: ~ # cronitor select
✔ /usr/bin/pacman -Syu --noconfirm
----► Running command: /usr/bin/pacman -Syu --noconfirm
:: Synchronizing package databases...
core is up to date
extra is up to date
community is up to date
multilib is up to date
:: Starting full system upgrade...
there is nothing to do
----► ✔ Command successful Elapsed time 0.893s
root@nowhere: ~ #
Again, make sure that you check pacman.log regularly like so, just in case any package breaks the arch installation:
[ 10.0.0.10/16 ] [ /dev/pts/73 ] [~]
→ tail -f /var/log/pacman.log
[2021-05-18T15:00:40+0200] [PACMAN] starting full system upgrade
[2021-05-18T15:16:17+0200] [PACMAN] Running 'pacman -Syu --noconfirm'
[2021-05-18T15:16:17+0200] [PACMAN] synchronizing package lists
[2021-05-18T15:16:18+0200] [PACMAN] starting full system upgrade
[2021-05-18T15:19:40+0200] [PACMAN] Running '/usr/bin/pacman -Syu --noconfirm'
[2021-05-18T15:19:40+0200] [PACMAN] synchronizing package lists
[2021-05-18T15:19:40+0200] [PACMAN] starting full system upgrade
[2021-05-18T15:20:38+0200] [PACMAN] Running '/usr/bin/pacman -Syu --noconfirm'
[2021-05-18T15:20:38+0200] [PACMAN] synchronizing package lists
[2021-05-18T15:20:38+0200] [PACMAN] starting full system upgrade
Or here's the way i like to do it:
[ 10.0.0.10/16 ] [ /dev/pts/68 ] [~/Videos]
→ cat /var/log/pacman.log | grep $(date --iso-8601)
[2021-05-19T02:00:01+0200] [PACMAN] Running '/usr/bin/pacman -Syu --noconfirm'
[2021-05-19T02:00:01+0200] [PACMAN] synchronizing package lists
[2021-05-19T02:00:03+0200] [PACMAN] starting full system upgrade
[2021-05-19T02:00:54+0200] [ALPM] transaction started
[2021-05-19T02:00:54+0200] [ALPM] upgraded ca-certificates-mozilla (3.64-1 -> 3.65-1)
[2021-05-19T02:00:54+0200] [ALPM] upgraded libx11 (1.7.0-4 -> 1.7.1-1)
[2021-05-19T02:00:54+0200] [ALPM] upgraded pango (1:1.48.4-1 -> 1:1.48.5-1)
[2021-05-19T02:00:54+0200] [ALPM] upgraded nvidia-utils (465.27-1 -> 465.31-1)
[2021-05-19T02:00:54+0200] [ALPM-SCRIPTLET] If you run into trouble with CUDA not being available, run nvidia-modprobe first.
[2021-05-19T02:00:54+0200] [ALPM] upgraded nss (3.64-1 -> 3.65-1)
[2021-05-19T02:00:54+0200] [ALPM] upgraded gnome-shell (1:40.1-1 -> 1:40.1-2)
[2021-05-19T02:00:54+0200] [ALPM] upgraded imagemagick (7.0.11.12-1 -> 7.0.11.13-1)
[2021-05-19T02:00:54+0200] [ALPM] upgraded nvidia (465.27-10 -> 465.31-1)
[2021-05-19T02:00:55+0200] [ALPM] upgraded opencl-nvidia (465.27-1 -> 465.31-1)
[2021-05-19T02:00:55+0200] [ALPM] transaction completed
[2021-05-19T02:00:55+0200] [ALPM] running '20-systemd-sysusers.hook'...
[2021-05-19T02:00:55+0200] [ALPM] running '30-systemd-daemon-reload.hook'...
[2021-05-19T02:00:55+0200] [ALPM] running '30-systemd-update.hook'...
[2021-05-19T02:00:55+0200] [ALPM] running '40-update-ca-trust.hook'...
[2021-05-19T02:00:56+0200] [ALPM] running '60-depmod.hook'...
[2021-05-19T02:01:06+0200] [ALPM] running 'detect-old-perl-modules.hook'...
[2021-05-19T02:01:06+0200] [ALPM] running 'glib-compile-schemas.hook'...
[2021-05-19T02:01:06+0200] [ALPM] running 'gtk-update-icon-cache.hook'...
[2021-05-19T02:01:06+0200] [ALPM] running 'update-desktop-database.hook'...
you can make a bashrc / zshrc alias for it:
[ 10.0.0.10/16 ] [ /dev/pts/68 ] [~/Videos]
→ vim ~/.zshrc
checkpac(){
cat /var/log/pacman.log | grep $(date --iso-8601)
}
:wq
[ 10.0.0.10/16 ] [ /dev/pts/68 ] [~/Videos]
→ zsh
[ 10.0.0.10/16 ] [ /dev/pts/68 ] [~/Videos]
→ checkpac
[2021-05-19T02:00:01+0200] [PACMAN] Running '/usr/bin/pacman -Syu --noconfirm'
[2021-05-19T02:00:01+0200] [PACMAN] synchronizing package lists
[2021-05-19T02:00:03+0200] [PACMAN] starting full system upgrade
[2021-05-19T02:00:54+0200] [ALPM] transaction started
[2021-05-19T02:00:54+0200] [ALPM] upgraded ca-certificates-mozilla (3.64-1 -> 3.65-1)
[2021-05-19T02:00:54+0200] [ALPM] upgraded libx11 (1.7.0-4 -> 1.7.1-1)
[2021-05-19T02:00:54+0200] [ALPM] upgraded pango (1:1.48.4-1 -> 1:1.48.5-1)
[2021-05-19T02:00:54+0200] [ALPM] upgraded nvidia-utils (465.27-1 -> 465.31-1)
[2021-05-19T02:00:54+0200] [ALPM-SCRIPTLET] If you run into trouble with CUDA not being available, run nvidia-modprobe first.
[2021-05-19T02:00:54+0200] [ALPM] upgraded nss (3.64-1 -> 3.65-1)
[2021-05-19T02:00:54+0200] [ALPM] upgraded gnome-shell (1:40.1-1 -> 1:40.1-2)
[2021-05-19T02:00:54+0200] [ALPM] upgraded imagemagick (7.0.11.12-1 -> 7.0.11.13-1)
[2021-05-19T02:00:54+0200] [ALPM] upgraded nvidia (465.27-10 -> 465.31-1)
[2021-05-19T02:00:55+0200] [ALPM] upgraded opencl-nvidia (465.27-1 -> 465.31-1)
[2021-05-19T02:00:55+0200] [ALPM] transaction completed
[2021-05-19T02:00:55+0200] [ALPM] running '20-systemd-sysusers.hook'...
[2021-05-19T02:00:55+0200] [ALPM] running '30-systemd-daemon-reload.hook'...
[2021-05-19T02:00:55+0200] [ALPM] running '30-systemd-update.hook'...
[2021-05-19T02:00:55+0200] [ALPM] running '40-update-ca-trust.hook'...
[2021-05-19T02:00:56+0200] [ALPM] running '60-depmod.hook'...
[2021-05-19T02:01:06+0200] [ALPM] running 'detect-old-perl-modules.hook'...
[2021-05-19T02:01:06+0200] [ALPM] running 'glib-compile-schemas.hook'...
[2021-05-19T02:01:06+0200] [ALPM] running 'gtk-update-icon-cache.hook'...
[2021-05-19T02:01:06+0200] [ALPM] running 'update-desktop-database.hook'...
And that's it! We have covered the vast majority of linux distros being debian-based and arch-based to be able to automatically update thanks to cronjobs.
Donate XMR: 8AUYjhQeG3D5aodJDtqG499N5jXXM71gYKD8LgSsFB9BUV1o7muLv3DXHoydRTK4SZaaUBq4EAUqpZHLrX2VZLH71Jrd9k8
Contact: nihilist@contact.nowhere.moe (PGP)